﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Net;
using Newtonsoft.Json;
using Microsoft.Win32;
using System.Diagnostics;
using System.Security.AccessControl;
using System.Security.Cryptography;
using System.Drawing;
using Newtonsoft.Json.Serialization;

namespace DevicesView.Logic
{
    public class FileLogic
    {
        /// <summary>
        /// 为文件添加users，everyone用户组的完全控制权限
        /// </summary>
        /// <param name="filePath"></param>
        public static void AddSecurityControll2File(string filePath)
        {
            FileInfo fileInfo = new FileInfo(filePath);
            //获得该文件的访问权限
            System.Security.AccessControl.FileSecurity fileSecurity = fileInfo.GetAccessControl();
            //添加ereryone用户组的访问权限规则 完全控制权限
            fileSecurity.AddAccessRule(new FileSystemAccessRule("Everyone", FileSystemRights.FullControl, AccessControlType.Allow));
            //添加Users用户组的访问权限规则 完全控制权限
            fileSecurity.AddAccessRule(new FileSystemAccessRule("Users", FileSystemRights.FullControl, AccessControlType.Allow));
            //设置访问权限
            fileInfo.SetAccessControl(fileSecurity);
        }

        public static void AddSecurityControll2DirectoryInfo(string filePath)
        {
            DirectoryInfo info = new DirectoryInfo(filePath);
            //获得该文件的访问权限
            System.Security.AccessControl.DirectorySecurity fileSecurity = info.GetAccessControl();
            //添加ereryone用户组的访问权限规则 完全控制权限
            fileSecurity.AddAccessRule(new FileSystemAccessRule("Everyone", FileSystemRights.FullControl, AccessControlType.Allow));
            //添加Users用户组的访问权限规则 完全控制权限
            fileSecurity.AddAccessRule(new FileSystemAccessRule("Users", FileSystemRights.FullControl, AccessControlType.Allow));
            //设置访问权限
            info.SetAccessControl(fileSecurity);
        }


        public static bool GetWebFileToLocal(string httpUrl, string localPath, Action<int, int> callback = null, bool overwrite = true)
        {
            HttpResult<byte[]> head = WebLogic.GetHttpResult<byte[]>(new HttpItem { Method = HttpMethod.Head, Url = httpUrl });
            if (head.Result == null)
                return false;

            int fileLength = head.Result.Length;
            int count = 2048 * 1024;
            int index = -1;
            int loftindex = count;
            using (FileStream fs = System.IO.File.Create(localPath))
            {
                FileLogic.AddSecurityControll2File(localPath);
                do
                {
                    List<string> hreads = new List<string>();
                    loftindex = (index + count >= fileLength) ? fileLength - 1 : index + count;
                    hreads.Add(string.Format("Range: bytes={0}-{1}", index + 1, loftindex));
                    HttpResult<byte[]> hr = WebLogic.GetHttpResult<byte[]>(new HttpItem { Headers = hreads, Method = HttpMethod.Get, Url = httpUrl });
                    if (hr.Success)
                    {
                        fs.Write(hr.Result, 0, hr.Result.Length);
                        index += count;
                        if (callback != null)
                            callback(index + 1, fileLength);
                    }
                } while (index < fileLength);
            }
            return true;
        }


        public static bool DownloadFile(string url, string dest, Action<Point> collback = null)
        {
            if (!Directory.Exists(Path.GetDirectoryName(dest)))
                Directory.CreateDirectory(Path.GetDirectoryName(dest));

            HttpResult<byte[]> head = WebLogic.GetHttpResult<byte[]>(new HttpItem { Method = HttpMethod.Head, Url = url });
            if (head.Result == null)
            {
                System.IO.File.Create(dest);
                return false;
            }
            int fileLength = head.Result.Length;
            int count = 2048 * 1024;
            int index = -1;
            int loftindex = count;
            using (FileStream fs = System.IO.File.Create(dest))
            {
                FileLogic.AddSecurityControll2File(dest);
                do
                {
                    List<string> hreads = new List<string>();
                    loftindex = (index + count >= fileLength) ? fileLength - 1 : index + count;
                    hreads.Add(string.Format("Range: bytes={0}-{1}", index + 1, loftindex));
                    HttpResult<byte[]> hr = WebLogic.GetHttpResult<byte[]>(new HttpItem { Headers = hreads, Method = HttpMethod.Get, Url = url });
                    if (hr.Success)
                    {
                        fs.Write(hr.Result, 0, hr.Result.Length);
                        index += count;
                        collback?.Invoke(new Point(index + 1, (int)fileLength));
                    }
                } while (index < fileLength);
            }
            return true;
        }


        public static string GetFileMD5(byte[] buffer)
        {
            MD5 filemd5 = new MD5CryptoServiceProvider();
            byte[] retVal = filemd5.ComputeHash(buffer);
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < retVal.Length; i++)
                sb.Append(retVal[i].ToString("x2"));
            return sb.ToString();
        }

        public static string GetFileMD5(string path)
        {
            if (!File.Exists(path))
                return null;
           
            using (FileStream fs = File.OpenRead(path))
            {
                byte[] buffer = new byte[fs.Length];
                fs.Read(buffer,0,(int)fs.Length);
                return GetFileMD5(buffer);
            }
        }
    }
}
